package net.gdface.facedb;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.gitee.l0km.codegen.annotations.DeriveMethod;
import com.gitee.l0km.com4j.base.exception.NotFoundBeanException;
import com.gitee.l0km.ximage.ImageErrorException;
import com.gitee.l0km.ximage.MatType;

import net.gdface.facedb.db.FaceBean;
import net.gdface.facedb.db.FeatureBean;
import net.gdface.facedb.db.ImageBean;
import net.gdface.sdk.CodeInfo;
import net.gdface.sdk.CompareResult;
import net.gdface.sdk.FRect;
import net.gdface.sdk.FaceApi;
import net.gdface.sdk.NotFaceDetectedException;

/**
 * Face人脸数据库操作接口
 * @author guyadong
 *
 */
public interface FaceDb {
	/**
	 * 先对图像数据进行人脸检测，然后提取人脸特征码<br>
	 * 返回所有成功提取特征码的{@link CodeInfo}数组,没有检测到人脸则返回空数组
	 * @param imgData
	 *            图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
	 * @return {@link CodeInfo}数组<br>
	 * @throws ImageErrorException
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	public CodeInfo[] detectAndGetCodeInfo(byte[] imgData) throws ImageErrorException;
	/**
	 * 先对图像数据进行人脸检测，然后提取人脸特征码<br>
	 * 返回所有成功提取特征码的{@link CodeInfo}数组,没有检测到人脸则返回空数组
	 * @param matType 图像矩阵类型
	 * @param matData 图像矩阵
	 * @param width 图像宽度
	 * @param height 图像高度
	 * @return {@link CodeInfo}数组<br>
	 * @throws ImageErrorException
	 */
	@DeriveMethod(methodSuffix="Mat",localResolvedTypes={ByteBuffer.class})
	public CodeInfo[] detectAndGetCodeInfo(MatType matType, byte[] matData, int width, int height) throws ImageErrorException;

	/**
	 * 保存人脸特征到数据库<br>
	 * 多张人脸图像合成一个特征(适用于红外算法)
	 * @param feature 人脸特征数据
	 * @param faces 人脸图像和人脸位置数据一一对应的MAP
	 * @return 特征码MD5 id
	 * @throws DuplicateRecordException
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	FeatureBean addFeature(byte[] feature,Map<ByteBuffer,CodeInfo> faces)	throws DuplicateRecordException;

	/**
	 * 将已经提取特征码的图像和特征码信息存入数据库<br>
	 * @param imgData 图像数据
	 * @param features 包含特征数据的{@link CodeInfo}列表
	 * @throws DuplicateRecordException
	 * @return 图像数据MD5 id
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	ImageBean addImage(byte[] imgData, List<CodeInfo> features) throws DuplicateRecordException;

	/**
	 * 提取图像中最中心的人脸特征，并在数据库中搜索人脸<br>
	 * 如果存在大于相似度阀值(similarty)记录，则返回相似度最高的记录，否则将该图像添加入人脸数据库(只有一张人脸)
	 * @param imgData 包含图像的字节数组,该参数不能为null
	 * @param code 
	 *				人脸特征码信息<br>
	 * 				如果为{@code null}则先对图像进行人脸检测并提取特征,不为{@code null}时必须包含基本的人脸位置信息,此时将跳过人脸检测直接根据这些信息提取人脸特征<br>
	 *				然后将此提取到的人脸特征在数据库中进行人脸搜索
	 * @param similarty
	 * 				相似度阀值
	 * @return 图像数据MD5 id
	 * @throws NotFaceDetectedException
	 * @throws ImageErrorException
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#detectCenterFace(byte[])
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	ImageBean addImageIfAbsent(byte[] imgData, CodeInfo code, double similarty)
			throws NotFaceDetectedException, ImageErrorException;
	/**
	 * 特征码比对<br>
	 * 将{@code feature}与数据库中的特征码(根据{@code featureId}查询获取)比对，返回相似度结果
	 * 
	 * @param featureId
	 *            特征码ID(primary key 也是特征码的md5校验码),<br>
	 *            为 {@code null}或为空时抛出 {@link IllegalArgumentException}
	 * @param feature
	 *            特征码数据,为 {@code null}或为空时抛出 {@link IllegalArgumentException}
	 * @return 相似度结果(0.0~1.0)
	 * @throws NotFoundBeanException 没有找到{@code featureId}指定的数据库记录
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#compareCode(byte[], byte[])
	 */
	double compareFeature(String featureId,byte[] feature) throws NotFoundBeanException;

	/**
	 * 数据库特征码1:1比对 根据特征码id较验码比较数据库中两条人脸特征码的相似度
	 * 
	 * @param featureId1
	 *            特征码ID(primary key 也是特征码的md5校验码)
	 * @param featureId2
	 *            特征码ID(primary key)
	 * @return 相似度(0.0~1.0) 找不到记录则抛出异常
	 * @throws NotFoundBeanException
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#compareCode(byte[], byte[])
	 */
	double compareFeatureId(String featureId1,String featureId2) throws NotFoundBeanException;

	/**
	 * 1:N比对<br>
	 * 将一组人脸特征码{@code features}与数据库中指定的特征码{@code featureId}比较，返回相似度结果数组(0.0~1.0)<br>
	 * 比如将数据库中的一个特征码与一张图像中检测到的所有人脸进行比对.
	 * 
	 * @param featureId
	 *            特征码ID(primary key 也是特征码的md5校验码),为{@code null}或空时抛出 {@link IllegalArgumentException}
	 * @param features
	 *            包含人脸特征码信息对象数组,为{@code null}时抛出 {@link IllegalArgumentException}
	 * @return 包含比对相似度结果的数组,下标与{@code codes}对应<br>
	 *         如果codes中元素的特征码为null则对应的返回数组中元素为0
	 * @throws NotFoundBeanException
	 *             没在数据库中找到featureMd5指定的记录
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#compareCodes(byte[], CodeInfo[])
	 */
	double[] compareFeatures(String featureId, CodeInfo[] features) throws NotFoundBeanException;

	/**
	 * 数据库中指定的特征码与照片中所有的人脸相比，返回相似度结果<br>
	 * 
	 * @param featureId 特征码MD5 校验码
	 * @param imgData
	 *            图像数据字节数组
	 * @param facePos
	 *            检测到的人脸位置数组,参见{@link FaceApi#getCodeInfo(byte[], int, CodeInfo[])}同名参数
	 * @return 与输入数组下标对应的相似度(0.0~1.0)结果数组
	 * @throws NotFoundBeanException
	 * @throws NotFaceDetectedException
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#getCodeInfo(byte[], int, CodeInfo[])
	 * @see #compareFaces(String, byte[], CodeInfo[])
	 */
	double[] compareFaces(String featureId,
			byte[] imgData, CodeInfo[] facePos) throws NotFoundBeanException, NotFaceDetectedException;

	/**
	 * 从数据库(IMAGE表)中删除指定的图片，同时也删除对应的 FACE 表中的人脸信息
	 * @param imgMd5
	 *            图片MD5校验码字符串
	 * @param cascade 是否删除FACE表中关联的FEATURE表记录
	 * @return 删除成功则返回true,否则抛出异常
	 */
	boolean deleteImage(final String imgMd5, final boolean cascade);

	/**
	 * 从数据库(image表)中删除指定的图片
	 * 
	 * @param imgMd5List
	 *            图片MD5校验码字符串数组
	 * @param cascade 是否删除FACE表中关联的FEATURE表记录
	 * @return 返回删除的记录数
	 * @see #deleteImage(String,boolean)
	 */
	int deleteImages(List<String> imgMd5List, boolean cascade);

	/**
	 * 从数据库(FEATURE表)中删除指定的特征，同时也删除对应的FACE表中的人脸信息
	 * 
	 * @param featureId
	 *           特征码ID(primary key 也是特征码的md5校验码)
	 * @param cascade 是否删除FACE表中关联的IMAGE表记录
	 * @return 删除成功则返回true,否则抛出异常
	 */
	boolean deleteFeature(String featureId, boolean cascade);
	/**
	 * 从数据库(FEATURE表)中删除指定的一组特征
	 * @param featureIdList 
	 *           特征码ID列表(primary key 也是特征码的md5校验码)
	 * @param cascade 是否删除FACE表中关联的IMAGE表记录
	 * @return 返回删除的记录数
	 * @see #deleteFeature(String, boolean)
	 */
	int deleteFeatures(final List<String> featureIdList, final boolean cascade);

	/**
	 * 从对图像进行人脸检测并提取特征码然后加入数据库(IMAGE,FEATURE,FACE表) <br>
	 * @param imgData 图像数据
	 * @param faceNum see also {@link FaceApi#detectAndGetCodeInfo(byte[], int, FRect)}
	 * @return 保存到数据库中的图像数据记录
	 * @throws NotFaceDetectedException
	 * @throws DuplicateRecordException
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @throws ImageErrorException
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	ImageBean detectAndAddFeatures(byte[] imgData, int faceNum) throws DuplicateRecordException, ImageErrorException, NotFaceDetectedException;

	/**
	 * 对图像数据进行人脸检测并提取特征码,<br>
	 * 然后与数据库中指定的特征码相比，返回人脸特征数据及相似度结果
	 * 
	 * @param featureId
	 *            特征码ID(primary key 也是特征码的md5校验码)
	 * @param imgData
	 *            图片字节数组
	 * @param faceNum
	 *            参见 {@link FaceApi#detectAndGetCodeInfo(byte[], int, FRect)}同名参数
	 * @return 包含比对相似度结果的映射，{CodeInfo - 相似度}值对
	 * @throws NotFoundBeanException
	 * @throws ImageErrorException 
	 * @throws NotFaceDetectedException 
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#compareFaces(byte[], byte[], int, FRect)
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	CompareResult detectAndCompareFaces(String featureId,
			byte[] imgData, int faceNum) throws NotFoundBeanException,
			ImageErrorException, NotFaceDetectedException;

	/**
	 * 对{@code detectRectangle}指定的范围检测人脸并提取特征码(唯一),然后在数据库中搜索相似的人脸返回搜索结果<br>
	 * 图像({@code imgData})中只有一张人脸，否则抛出{@link NotFaceDetectedException}异常
	 * 
	 * @param imgData
	 *            图片字节数组
	 * @param similarty 相似度阀值
	 * @param rows 最多返回的记录数目
	 * @param where
	 *            参见 {@link #searchFeatures(byte[], double, int, String)}
	 * @return 包含搜索结果数组的{@link SearchResult}数组，出错则返回成员为null的{@link SearchResult }数组
	 * @throws ImageErrorException -
	 * @throws NotFaceDetectedException -
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#detectAndGetCodeInfo(byte[], int, FRect)
	 * @see #searchFeatures(byte[], double, int, String)
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	SearchResult[] detectAndSearchFaces(byte[] imgData, double similarty, int rows,
			String where) throws ImageErrorException, NotFaceDetectedException;

	/**
	 * 返回{@code faceId}对应的FEATURE记录
	 * @param faceId 人脸记录ID
	 * @return 如果记录不存在返回{@code null}
	 */
	FeatureBean getFeatureByFaceId(int faceId);
	/**
	 * 通过特征码id获取指定的数据库记录
	 * 
	 * @param featureId
	 *            特征码ID(primary key 也是特征码的md5校验码),<br>
	 *            为 {@code null}或为空时抛出 {@link IllegalArgumentException}
	 * @return 返回指定的记录对象，记录不存在则返回null
	 */
	FeatureBean getFeature(String featureId);

	/**
	 * 根据图片的md5校验码查找数据库中属于该图片的所有人脸特征数据库对象
	 * 
	 * @param imageMd5
	 *            图片md5校验码字符串,为 {@code null}或为空时抛出 {@link IllegalArgumentException}
	 * @return 如果记录不存在返回空表
	 */
	List<FeatureBean> getFeaturesByImageMd5(String imageMd5);

	/**
	 * 根据图片的md5校验码查找数据库中属于该图片的唯一人脸特征数据库对象<br>
	 * 如果结果不唯一则抛出异常
	 * @param imageMd5 图片的md5校验码
	 * @return 如果记录不存在返回{@code null}
	 * @see #getFeaturesByImageMd5(String)
	 */
	FeatureBean getFeatureByImageMd5(String imageMd5);

	/**
	 * 根据特征码的md5 id获取数据库对应的FACE表记录<br>
	 * 如果结果不唯一则抛出异常
	 * @param featureId 特征码md5 id,为 {@code null}或为空时抛出 {@link IllegalArgumentException}
	 * @return 没找到记录返回null
	 * @see #getFacesByFeatureId(String)
	 */
	FaceBean getFaceByFeatureId(String featureId);
	
	/**
	 * 根据图片的md5校验码查找数据库中属于该图片的所有人脸特征FACE表记录（包含人脸，人眼位置信息）
	 * 
	 * @param imageMd5 图片的md5校验码
	 * @return imageMd5为null或没有找到记录则返回空数组
	 */
	List<FaceBean> getFacesByImageMd5(String imageMd5);

	/**
	 * 返回{@code imageMd5}主键指定图像中对应FACE表记录<br>
	 * 如果结果不唯一则抛出异常
	 * @param imageMd5 图片的md5校验码
	 * @return 如果记录不存在返回{@code null}
	 */
	FaceBean getFaceByImageMd5(String imageMd5);

	/**
	 * 返回人脸特征id{@code featureId}对应的{@code CodeInfo}对象列表<br>
	 * @param featureId 特征码的md5 校验码
	 * @return 如果记录不存在返回空表
	 * @see #getCodeInfo(int)
	 */
	List<CodeInfo> getCodeInfosByFeatureId(String featureId);

	/**
	 * 返回人脸特征id{@code featureId}对应的{@code CodeInfo}对象<br>
	 * 如果结果不唯一则抛出异常
	 * @param featureId 特征码的md5 校验码
	 * @return 如果记录不存在返回{@code null}
	 * @see #getFaceByFeatureId(String)
	 * @see #getCodeInfo(int)
	 */
	CodeInfo getCodeInfoByFeatureId(String featureId);

	/**
	 * 返回 {@code faceId}主键指定的FACE表记录并转为{@code CodeInfo}人脸信息(包含特征数据)对象返回<br>
	 * 如果结果不唯一则抛出异常
	 * @param faceId 人脸记录ID
	 * @return 如果记录不存在返回{@code null}
	 * @see #getFace(int)
	 */
	CodeInfo getCodeInfo(int faceId);

	/**
	 * 返回 {@code imageMd5}指定的FACE表记录列表并转为{@code CodeInfo}人脸信息(包含特征数据)对象返回<br>
	 * @param imageMd5 图片的md5校验码
	 * @return 如果记录不存在返回空表
	 */
	List<CodeInfo> getCodeInfosByImageMd5(String imageMd5);

	/**
	 * 返回{@code imageMd5}主键指定图像对应的FACE表记录并转为{@code CodeInfo}人脸信息(包含特征数据)对象返回<br>
	 * 如果结果不唯一则抛出异常
	 * @param imageMd5 图片的md5校验码
	 * @return 如果记录不存在返回{@code null}
	 * @see #getFaceByImageMd5(String)
	 */
	CodeInfo getCodeInfoByImageMd5(String imageMd5);

	/**
	 * 通过图像数据库的MD5校验码查找image表记录
	 * 
	 * @param imageMd5
	 *            图片的md5校验码
	 * @return 没有找到记录时返回null，成功返回指定的数据库记录
	 */
	ImageBean getImage(String imageMd5);
	/**
	 * 根据数据库表的主键值返回图像记录
	 * @param primaryKey 数据库表的主键值,根据 refType的类型不同，primaryKey代表不同表的主键(类型为整数的主键需要转为十进制字符串)
	 * @param refType 指定 primaryKey 的引用类型,如下:
	 * 					<ul>
	 * 						<li>DEFAULT 返回 fd_image表指定的图像数据</li>
	 * 						<li>IMAGE 返回 fd_image表指定的图像数据</li>
	 * 						<li>FACE 返回 fd_face表中的image_md5字段指定的图像数据</li>
	 * 						<li>FEATURE  返回提取fd_feature表中的md5字段指定特征的图像数据(对于多张人脸图像合成的特征无效)</li>
	 * 					</ul>
	 * 				<br>为{@code null}则默认为DEFAULT
	 * @return {@link ImageBean} ,如果没有对应记录则返回null
	 */	
	@DeriveMethod(methodSuffix="Ref")
	ImageBean getImage(String primaryKey, String refType);

	/**
	 * 返回faceId对应的 IMAGE 记录
	 * @param faceId 人脸记录ID
	 * @return IMAGE 记录
	 */
	ImageBean getImageByFaceId(int faceId);

	/**
	 * 返回 {@code imageMd5}指定的图像数据<br>
	 * 返回图像数据字节数组，找不到记录则返回{@code null}
	 * @param imageMd5 图片的md5校验码
	 * @return 图像数据字节数组
	 */
	byte[] getImageBytes(String imageMd5);
	
	/**
	 * 返回primaryKey和refType指定的图像数据<br>
	 * 返回图像数据字节数组，找不到记录则返回{@code null}
	 * @param primaryKey 数据库表的主键值,参见 {@link #getImage(String, String)}定义
	 * @param refType primaryKey的类型,参见 {@link #getImage(String, String)}定义
	 * @return 图像数据字节数组
	 */
	@DeriveMethod(methodSuffix="Ref")
	byte[] getImageBytes(String primaryKey, String refType);

	/**
	 * 根据特征码的md5 id获取数据库对应的IMAGE表记录<br>
	 * 如果结果不唯一则抛出异常
	 * @param featureId 特征码的md5 校验码
	 * @return IMAGE 记录
	 */
	public ImageBean getImageByFeatureId(String featureId);
	/**
	 * 根据特征码的md5 id获取数据库对应的IMAGE表记录
	 * @param featureId  特征码的md5 校验码
	 * @return IMAGE表主键数组
	 */
	List<ImageBean> getImagesByFeatureId(String featureId);

	/**
	 * 返回 {@code faceId}主键指定的FACE表记录
	 * @param faceId 人脸记录ID
	 * @return 如果记录不存在返回{@code null}
	 */
	FaceBean getFace(int faceId);

	/**
	 * 根据特征码的md5 id获取数据库对应的FACE表记录(多张人脸合成)
	 * @param featureId 人脸特征码md5 校验码
	 * @return FACE 表主键数组
	 */
	List<FaceBean> getFacesByFeatureId(String featureId);

	/**
	 * 通过MD5校验码来判断数据库中是否存在同样的特征码
	 * 
	 * @param feature
	 *            特征码字节数组
	 * @return 如果没有则返回false，否则返回true
	 */
	boolean hasFeature(byte[] feature);

	/**
	 * 通过MD5校验码来判断数据库中是否存在同样的特征码
	 * 
	 * @param featureId
	 *            特征码的MD5校验码
	 * @return 如果没有则返回false，否则返回true
	 */
	boolean hasFeatureByMD5(String featureId);

	/**
	 * 通过MD5校验码来判断数据库中是否存在同样的图像
	 * @param imageMd5 图片的md5校验码
	 * @return 如果没有则返回false，否则返回true
	 */
	boolean hasImage(String imageMd5);

	/**
	 * 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。
	 * 返回包含相似度计算结果的{@link SearchResult}数组<br>
	 * 相似度值通过 {@link SearchResult#getSimilarity()} 获取,对应的人脸特征ID由 {@link SearchResult#getFeatureId()}获取
	 * @param imgData
	 *            图片字节数组
	 * @param facePos
	 *            人脸位置对象<br>
	 *            为{@code null}时,先做人脸检测再提取特征码<br>
	 *            不为{@code null}时,直接在指定的位置提取特征码<br>
	 * @param similarty 相似度阀值
	 * @param rows 最多返回的记录数目
	 * @param where (忽略)条件查询的where语句的条件部分，为{@code null}时全表比对
	 * @return 包含相似度计算结果的{@link SearchResult}数组<br>
	 * @throws NotFaceDetectedException -
	 * @throws ImageErrorException -
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#getCodeInfo(byte[], int, CodeInfo[])
	 * @see #searchFeatures(byte[], double, int, String)
	 */
	@DeriveMethod(localResolvedTypes={InputStream.class,URL.class,File.class,ByteBuffer.class})
	SearchResult[] searchFaces(byte[] imgData, CodeInfo facePos, double similarty, int rows,
			String where) throws NotFaceDetectedException, ImageErrorException;
	/**
	 * 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。
	 * 返回包含相似度计算结果的{@link SearchResult}数组<br>
	 * 相似度值通过 {@link SearchResult#getSimilarity()} 获取,对应的人脸特征ID由 {@link SearchResult#getFeatureId()}获取
	 * @param matType 图像矩阵类型
	 * @param matData 图像矩阵
	 * @param width 图像宽度
	 * @param height 图像高度
	 * @param facePos
	 *            人脸位置对象<br>
	 *            为{@code null}时,先做人脸检测再提取特征码<br>
	 *            不为{@code null}时,直接在指定的位置提取特征码<br>
	 * @param similarty 相似度阀值
	 * @param rows 最多返回的记录数目
	 * @param where (忽略)条件查询的where语句的条件部分，为{@code null}时全表比对
	 * @return 包含相似度计算结果的{@link SearchResult}数组<br>
	 * @throws NotFaceDetectedException -
	 * @throws ImageErrorException -
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 * @see FaceApi#getCodeInfo(byte[], int, CodeInfo[])
	 * @see #searchFeatures(byte[], double, int, String)
	 */
	@DeriveMethod(methodSuffix="Mat",localResolvedTypes={ByteBuffer.class})
	SearchResult[] searchFaces(MatType matType, byte[] matData, int width, int height, CodeInfo facePos, double similarty, int rows,
	String where) throws NotFaceDetectedException;

	/**
	 * 搜索与{@code code}相似度大于{@code similarty}的记录(最多返回前{@code rows}个结果)<br>
	 * 返回包含相似度计算结果的{@link SearchResult}数组,
	 * 相似度值通过 {@link SearchResult#getSimilarity()} 获取,对应的人脸特征ID由 {@link SearchResult#getFeatureId()}获取<br>
	 * 返回结果以相似度降序排列。
	 * 
	 * @param feature
	 *            要搜索的特征码
	 * @param similarty
	 *            相似度阀值
	 * @param rows
	 *            最多返回的记录数目
	 * @param where (忽略)
	 *            条件查询的where语句的条件部分，为{@code null}时全表比对
	 * @return 包含相似度计算结果的{@link SearchResult}数组<br>
	 * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
	 */
	SearchResult[] searchFeatures(byte[] feature, double similarty, int rows, String where);

	/**
	 * SQL查询数据库返回image表的记录数目
	 * @param where SQL语句where条件字符串,为null返回所有记录数据
	 * @return 返回符合查询条件的记录数目
	 */
	int getImageCount(String where);
	/**
	 * SQL查询数据库返回face表的记录数目
	 * @param where SQL语句where条件字符串,为null返回所有记录数据
	 * @return 返回符合查询条件的记录数目
	 */
	int getFaceCount(String where);
	/**
	 * 返回内存code表的记录数目(不需要SQL查询)
	 * @return 特征记录数目
	 */
	int getFeatureCount();

	/** 
	 * 查询{@code where}条件指定的 fd_image 记录<br>
	 * @param where WHERE 条件语句
	 * @return 返回查询结果记录的主键
	 */
	List<String> loadImagesMd5ByWhere(String where);

	/** 
	 * (主动更新机制实现)<br>
	 * 返回 fd_feature.create_time 字段大于指定时间戳({@code timestamp})的所有记录
	 *  @param timestamp 时间戳
	 * @return 返回查询结果记录的主键列表
	 */
	List<String> loadFeaturesMd5ByCreateTime(Date timestamp);

	/**
	 * (主动更新机制实现)<br>
	 * 返回 fd_feature.create_time 字段大于指定时间戳({@code timestamp})的所有记录
     * @param timestamp 时间戳,{@code yyyy-MM-dd}或{@code yyyy-MM-dd HH:mm:ss}或{@code yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}(ISO8601)格式日期字符串
     * @return 返回查询结果记录的主键列表
     */
	@DeriveMethod(methodSuffix="TimeStr")
	List<String> loadFeaturesMd5ByCreateTime(String timestamp);

	/** 
	 * 返回 fd_image.create_time 字段大于指定时间戳({@code timestamp})的所有记录
	 * @param timestamp 时间戳
	 * @return 返回查询结果记录的主键列表
	 */
	List<String> loadImagesMd5ByCreateTime(Date timestamp);
	
	/** 
	 * 返回 fd_image.create_time 字段大于指定时间戳({@code timestamp})的所有记录
     * @param timestamp 时间戳,{@code yyyy-MM-dd}或{@code yyyy-MM-dd HH:mm:ss}或{@code yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}(ISO8601)格式日期字符串
	 * @return 返回查询结果记录的主键列表
	 */
	@DeriveMethod(methodSuffix="TimeStr")
	List<String> loadImagesMd5ByCreateTime(String timestamp);

	/** 
	 * 查询{@code where}条件指定的 fd_feature 记录
	 * @param where WHERE 条件语句
	 * @return 返回查询结果记录的主键列表
	 */
	List<String> loadFeaturesMd5ByWhere(String where);

	/**
	 * 通过SQL WHERE字符串查找image表记录
	 * 
	 * @param where WHERE 条件语句
	 * @param startRow 返回记录的起始行(首行=1,尾行=-1)
	 * @param numRows 返回记录条数(小于0时返回所有记录)
	 * @return 如果记录不存在返回空表
	 */
	List<ImageBean> loadImagesByWhere(String where, int startRow, int numRows);

	/**
	 * 返回当前接口实现方式
	 * 
	 * @return  本地实现返回true,返回false为 RPC远程实现
	 */
	boolean isLocal();

	/**
	 * 返回当前{@link FaceDb}实例特性(能力)描述,已定义字段:<br>
	 * <ul>
	 * <li>SUPPORT_SEARCH [boolean]是否支持人脸特征搜索(1:N对比)</li>
	 * <li>FACEAPI_ENABLE [boolean]是否有人脸识别算法(FaceApi实例)支持</li>
	 * </ul>
	 * 以上字段名常量定义参见{@link net.gdface.facedb.CapcityFieldConstant}
	 * 如果数据库有人脸识别算法支持则还会定义如下字段:
	 * <ul>
	 * <li>C_SUPPORT_SEARCH [boolean]是否支持人脸特征搜索(1:N对比)</li>
	 * <li>SDK_VERSION [string]SDK版本号</li>
	 * <li>MULTI_FACE_FEATURE [boolean]算法是否支持多人脸合成特征</li>
	 * <li>FACE_LIVE [boolean]是否支持活体检测</li>
	 * <li>WEAR_MASK [boolean]是否支持口罩检测</li>
	 * <li>FDDATA_SIZE [int]人脸检测数据的(byte)长度</li>
	 * <li>FEATURE_SIZE [int]人脸特征数据(byte)长度</li>
	 * <li>MAX_FACE_COUNT [int]最大检测人脸数目</li>
	 * <li>FSE_ENABLE [boolean]是否支持特征内存搜索引擎</li>
	 * <li>CODEINFO_RELOCATE [boolean]是否支持CodeInfo对象重定位</li>
	 * <li>LOCAL_DETECT [boolean] 人脸检测是否为本地实现,未定义则为false</li>
	 * </ul>
	 * 以上字段名常量定义参见{@link net.gdface.sdk.CapcityFieldConstant}
	 * @return key-value 对描述算法能力的映射
	 */
	Map<String, String> dbCapacity();
}